package site.shader85.Kingdoms.domain.area;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bukkit.Location;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;


@SerializableAs("Area")
public class Area implements ConfigurationSerializable{

	private final int beginX;
	private final int endX;
	private final int beginY;
	private final int endY;
	private final int beginZ;
	private final int endZ;
	private final Position[] apex;
	
	public static void main(String args[]){
		
	}
	
	public Area(Position begin, Position end) {
		beginX = getMin(begin.x, end.x);
		endX = getMax(begin.x, end.x);
		beginY = getMin(begin.y, end.y);
		endY = getMax(begin.y, end.y);
		beginZ = getMin(begin.z, end.z);
		endZ = getMax(begin.z, end.z);
		List<Position> pos = Lists.newArrayList();
		for (int x : new int[] { beginX, endX }) {
			for (int y : new int[] { beginY, endY }) {
				for (int z : new int[] { beginZ, endZ }) {
					pos.add(Position.getPosition(x, y, z));
				}
			}
		}
		apex = pos.toArray(new Position[0]);
	}

	public boolean inArea(Location loc) {
		return inArea(Position.byLocation(loc));
	}

	public boolean inArea(Position pos) {
		if (pos.x >= beginX && pos.x <= endX)
			if (pos.y >= beginY && pos.y <= endY)
				if (pos.z >= beginZ && pos.z <= endZ)
					return true;
		return false;
	}
	
	public boolean outArea(Area a){
		return !isCollisional(a);
	}
	
	public boolean inArea(Area a){
		int count = 0;
		for (Position pos : a.getApex()) {
			if (inArea(pos))
				count++;
		}
		return count == 8;
	}
	
	public int getHeight(){
		return this.endY-this.beginY+1;
	}
	
	public int getXZ(){
		return (this.endZ-this.beginZ+1)*(this.endX-this.beginX+1);
	}
	
	
	public boolean isCollisional(Area a) {
		for (Position pos : a.getApex()) {
			if (inArea(pos))
				return true;
		}
		return false;
	}
	
	public Position[] getApex() {
		return apex;
	}

	private int getMax(int a, int b) {
		return a > b ? a : b;
	}

	private int getMin(int a, int b) {
		return a < b ? a : b;
	}

	@Override
	public Map<String, Object> serialize() {
		HashMap<String, Object> table = Maps.newHashMap();
		Position pos1 = Position.getPosition(beginX, beginY, beginZ);
		Position pos2 = Position.getPosition(endX, endY, endZ);
		table.put("pos1", pos1);
		table.put("pos2", pos2);
		return table;
	}
	
	public static Area deserialize(Map<String, Object> table) {
		Position pos1 = (Position)table.get("pos1");
		Position pos2 = (Position)table.get("pos2");
		return new Area(pos1,pos2);
	}
}
